﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Bioinformatics.Types;
using System.Threading;


namespace Bioinformatics.UI
{
    public class GeneticSequenceDownloader
    {
        private Thread _downloadLoopThread;
        private ManualResetEvent _manualResetEvent = new ManualResetEvent(false);
        private Queue<GeneticSequenceDownload> _downloadQueue = new Queue<GeneticSequenceDownload>();
        
        public void AddDownload(GeneticSequenceDownload geneticSequenceDownload)
        {
            //lock the queue so nothing can be dequeued from it nor can the thread blocker be modified
            lock(_downloadQueue)
            {
                //add the download object from the queue
                _downloadQueue.Enqueue(geneticSequenceDownload);
                //ensure the thread blocker is set
                _manualResetEvent.Set();
            }
        }

        public void RemoveDownload(GeneticSequenceDownload geneticSequenceDownload)
        {
            //set flag on download object so its ignored
            if (geneticSequenceDownload.Status == CheckState.Checked)
                geneticSequenceDownload.Status = CheckState.Unchecked;
        }

        private void downloadLoop()
        {
            GeneticSequenceDownload currentDownload = null;
            for(;;)
            {
                //block thread - will block if reset or do nothing if set
                _manualResetEvent.WaitOne();

                //conditionally download the sequence
                if (currentDownload != null && currentDownload.Status != CheckState.Unchecked)
                    downloadGeneticSequence(currentDownload);
                
                //remove next item from queue - threadsafe
                lock (_downloadQueue)
                {
                    if (_downloadQueue.Count > 0)
                        currentDownload = _downloadQueue.Dequeue();
                    else
                        _manualResetEvent.Reset();
                }
            }
        }

        private void downloadGeneticSequence(GeneticSequenceDownload geneticSequenceDownload)
        {
            //var sequence = new char[int.Parse(geneticSequence.Length)];
            //int segmentCount = int.Parse(geneticSequence.Length) / 4096;
            //int remainderLength = int.Parse(geneticSequence.Length) % 4096;
            //var requestServer = new eUtilsServiceSoapClient();

            //uxProgressBar.Maximum = segmentCount;

            ////download entire segments
            //var thread = new Thread(() =>
            //{
            //    Parallel.For(0, segmentCount, i =>
            //    {
            //        if (_downloading)
            //        {
            //            var segmentRequest = new eFetchRequest();
            //            segmentRequest.db = "genome";
            //            segmentRequest.id = geneticSequence.Gi;
            //            segmentRequest.seq_start = (i * 4096).ToString();
            //            segmentRequest.seq_stop = ((i + 1) * 4096).ToString();
            //            eFetchResult segmentResult = requestServer.run_eFetch(segmentRequest);
            //            Array.Copy(segmentResult.GBSet.GBSeq[0].GBSeq_sequence.ToCharArray(), 0, sequence, i * 4096, 4096);
            //            incrementProgress();
            //        }
            //    });
            //});
            //thread.Start(); 
        }

        public void Start()
        {
            //start downloader thread
            _downloadLoopThread = new Thread(downloadLoop);
            _downloadLoopThread.Start();
        }

        public void Stop()
        {
            //stop downloader thread
            _downloadLoopThread.Abort();
        }
    }
}
